﻿using System.Windows.Input;

namespace System
{
	public struct ConsoleKeyInfo : IEquatable<ConsoleKeyInfo>
	{
		#region Public Properties
		public char KeyChar
		{
			get
			{
				return value;
			}
		}

		public ConsoleKey Key
		{
			get
			{
				return key;
			}
		}

		public ConsoleModifiers Modifiers
		{
			get
			{
				return mods;
			}
		}
		#endregion

		#region Private / Protected
		private readonly char value;
		private readonly ConsoleKey key;
		private readonly ConsoleModifiers mods;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="ConsoleKeyInfo" /> struct.
		/// </summary>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "char", 
			Justification = "Matches the .NET 4.0 BCL signature.")]
		public ConsoleKeyInfo(char keyChar, ConsoleKey key, bool shift, bool alt, bool control)
		{
			this.value = keyChar;
			this.key = key;

			mods = 0;

			if (shift)
			{
				mods |= ConsoleModifiers.Shift;
			}

			if (alt)
			{
				mods |= ConsoleModifiers.Alt;
			}

			if (control)
			{
				mods |= ConsoleModifiers.Control;
			}
		}
		#endregion

		#region Methods
		public bool Equals(ConsoleKeyInfo other)
		{
			return other.value == value
					&& other.key == key
					&& other.mods == mods;
		}

		public override bool Equals(object obj)
		{
			return obj is ConsoleKeyInfo && Equals((ConsoleKeyInfo) obj);
		}

		public override int GetHashCode()
		{
			return (int) (((ConsoleModifiers) value) | mods);
		}

		public static bool operator ==(ConsoleKeyInfo first, ConsoleKeyInfo second)
		{
			return first.Equals(second);
		}

		public static bool operator !=(ConsoleKeyInfo first, ConsoleKeyInfo second)
		{
			return !first.Equals(second);
		}
		#endregion
	}
}